#ifndef DriverMatrix_H
#define DriverMatrix_H


//!Includes
#include "../../Libs/ManipulacaoFrames/ManipulacaoFrames.h"
#include "../../Libs/ManipulacaoMatrizes/Matrizes.h"
#include <iostream>
#include <stdio.h>
#include <string.h>

//!Defines


//!Global Functions


namespace driver
{

/**
 * class DriverMatrix
 *
 * Autor:David Bevilaqua
 *
 * DESCRIPTION:
 *
 */

class DriverMatrix
{
public:

	//!Enums



	//!Constructors/Destructors

	/**
	 * Empty Constructor
	 */
	DriverMatrix ( );

	/**
	 * Empty Destructor
	 */

	~DriverMatrix ( );

	//!Public Attributes




	//!Public Accessor Methods



	//!Public Methods
	float **CppCriaMatriz(int NumeroLinhas,int NumeroColunas);
	float **CppApagaMatriz(float **A, int NumeroLinhas, int NumeroColunas);

	float  *CppCriaVetor(int NumeroElementos);
	float  *CppApagaVetor(float *A);

	float **CppMultiplicaMatriz(float **A,int LinhasA,int ColunasA,float **B,int LinhasB,int ColunasB);
	float **CppMultiplicaVetorDiagonal(float **A,int LinhasA,int ColunasA,float *B,int ElementosB);
	float  *CppMultiplicaVetor(float **A,int LinhasA,int ColunasA,float *B);
	float **CppMultiplicaConstante(float **A,int LinhasA,int ColunasA,float B);
	float  *CppMultiplicaConstante(float  *A,int ElementosA,float B);

	float **CppSomaMatriz(float **A,int LinhasA,int ColunasA,float **B);
	float **CppSubtraiMatriz(float **A,int LinhasA,int ColunasA,float **B);

	float   CppCalculaSomaElementos(float **Matriz,int NumLinhas,int NumColunas);
	float   CppCalculaSomaElementos(float *Vetor,int NumElementos);
	float   CppCalculaMediaElementos(float **Matriz,int NumLinhas,int NumColunas);
	float   CppCalculaMediaElementos(float *Vetor,int NumElementos);
	float   CppCalculaMaximoElemento(float **Matriz,int NumLinhas,int NumColunas);
	float   CppCalculaMaximoElemento(float *Vetor,int NumElementos);
	float   CppCalculaMinimoElemento(float **Matriz,int NumLinhas,int NumColunas);
	float   CppCalculaMinimoElemento(float *Vetor,int NumElementos);
	float   CppCalculaVarianciaElementos(float **Matriz,int NumLinhas,int NumColunas);
	float   CppCalculaVarianciaElementos(float *Vetor,int NumElementos);

	float **CppCalculaAdjunta(float **A,int NumLinhas);
	float **CppCalculaCofatores(float **Matriz,int NumLinhas);
	float **CppCalculaTransposta(float **A,int LinhasA,int ColunasA);
	float   CppCalculaDeterminante(float **Matriz,int NumLinhas);


	float **CppCalculaInversa   (float **Matriz,int NumLinhas);
	float **CppCalculaInversaLU (float **Matriz,int NumLinhas);
	float **CppCalculaInversaSVD(float **Matriz,int NumLinhas);



	float **CppRemoveColuna(float **Matriz,int NumLinhas, int NumColunas,int ColunaRemovida);
	float **CppRemoveLinha(float **Matriz,int NumLinhas, int NumColunas,int LinhaRemovida);

	int     CppFatoracaoLU(float **A,int LinhasMatriz,float **Permutacao);
	void    CppEliminacaoGaussJordan(float **A,float **B,int LinhasMatriz,int ColunasMatriz);
	int     CppDecomposicaoSVD(float **a, int m, int n, float *w, float **v);

	float  *CppSolucaoSistemaSVD(float **A,int NumLinhasA,int NumColunasA,float *B);
	float  *CppSolucaoSistemaGAUSS(float **A,int NumLinhasA,int NumColunasA,float *B);
	float  *CppSolucaoSistemaLU(float **MatrizFatoradaLU,int NumLinhas,float **Permutacao,float *Vetor);

	float  *CppCalculaAngulosEulerMatrizRotacao(float **Rw);

	float **Cpp_RotX(float Angulo);
	float **Cpp_RotY(float Angulo);
	float **Cpp_RotZ(float Angulo);
	float **Cpp_Trans(float X,float Y,float Z);
	float  *CppExtraiParametros(float **MatrizTransformacao);
	void    CppImprimirMatriz(float **Matriz, int NumeroLinhas, int NumeroColunas);

	void Execute ( );


protected:

	//!Protected Attributes



	//!Protected Methods



private:

	//!Private Attributes


	//!Private Methods
	void initAttributes ( );



};

};

#endif
